package com.alibaba.citrus.cr.sales.plan.facade.service.statistics;

import com.alibaba.citrus.cr.common.annotation.FacadeInvoker;
import com.alibaba.citrus.cr.common.exception.FacadeException;
import com.alibaba.citrus.cr.common.util.DateUtils;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.SalesPlanAdjustDetailSubTotalRequest;
import com.alibaba.citrus.cr.sales.plan.dto.api.response.SalesPlanSubTotalResponse;
import com.alibaba.citrus.cr.sales.plan.model.enums.SalesPlanStatusEnum;
import com.alibaba.citrus.cr.sales.plan.model.enums.SalesStatBizTypeEnum;
import com.alibaba.citrus.cr.sales.plan.repository.SalesPlanAdjustDetailRepository;
import com.alibaba.citrus.cr.sales.plan.repository.SalesPlanCustomerStatRepository;
import com.alibaba.citrus.cr.sales.plan.repository.SalesPlanLineRepository;
import com.alibaba.citrus.cr.sales.plan.repository.request.SalesPlanStatCustomerSubTotalRepoRequest;
import com.alibaba.citrus.cr.sales.plan.sdo.SalesPlanSDO;
import com.alibaba.citrus.cr.sales.plan.sdo.SalesPlanStatCustomerSDO;
import com.alibaba.citrus.cr.sales.plan.api.statistics.SalesPlanCustomerStatQueryService;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.DimensionDTO;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.PageQueryPlanCustomerStatRequest;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.SalesPlanStatCustomerSubTotalRequest;
import com.alibaba.citrus.cr.sales.plan.facade.service.SalesPlanCommonService;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.bosalesplancustomerindex.dto.PageQueryPlanCustomerRequest;
import com.epoch.app.bcorder.bosalesplancustomerindex.dto.PageQueryPlanCustomerResponse;
import com.epoch.app.bcorder.bosalesplancustomerindex.service.BoSalesPlanCustomerIndexService;
import com.epoch.app.bcorder.sales_plan.contract.dto.SubTotalCompanyCrmContractCountRequest;
import com.epoch.app.bcorder.sales_plan.contract.model.Contract;
import com.epoch.app.bcorder.sales_plan.contract.service.ContractService;
import com.epoch.app.bcorder.sales_plan.planscitemextend.dto.SubTotalCompanyReturnCountRequest;
import com.epoch.app.bcorder.sales_plan.planscitemextend.dto.SubTotalCompanyReturnCountResponse;
import com.epoch.app.bcorder.sales_plan.planscitemextend.service.PlanScItemExtendService;
import com.epoch.app.bcorder.sales_plan.salesplandetail.dto.SubTotalSalesPlanLineRequest;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author yuhailin
 * @description:
 * @date 2021-09-27 10:28
 */
@Component
public class SalesPlanCustomerStatQueryServiceImpl implements SalesPlanCustomerStatQueryService {
    @Resource
    private SalesPlanCustomerStatRepository salesPlanCustomerStatRepository;

    @Resource
    private SalesPlanCommonService salesPlanCommonService;

    @Resource
    private BoSalesPlanCustomerIndexService boSalesPlanCustomerIndexService;

    @Resource
    private PlanScItemExtendService planScItemExtendService;

    @Resource
    private ContractService contractService;

    @Resource
    private SalesPlanLineRepository salesPlanLineRepository;

    @Resource
    private SalesPlanAdjustDetailRepository salesPlanAdjustDetailRepository;

    @FacadeInvoker
    @Override
    public Result<PageResult<List<SalesPlanStatCustomerSDO>>> pageQueryPlanCustomerList(PageQueryPlanCustomerStatRequest pageQueryPlanCustomerStatRequest) {
        SalesPlanSDO salesPlan = salesPlanCommonService.checkSalesPlan(pageQueryPlanCustomerStatRequest.getPlanId());
        DimensionDTO dimension = salesPlanCommonService.checkBizType(salesPlan, pageQueryPlanCustomerStatRequest);
        PageQueryPlanCustomerRequest queryPlanCustomerRequest = new PageQueryPlanCustomerRequest();
        if (StringUtils.isNotBlank(pageQueryPlanCustomerStatRequest.getPlanId())){
            queryPlanCustomerRequest.setPlanIdList(Lists.newArrayList(pageQueryPlanCustomerStatRequest.getPlanId()));
        }
        if (StringUtils.isNotBlank(pageQueryPlanCustomerStatRequest.getCustomerCode())){
            queryPlanCustomerRequest.setCustomerCodeList(Lists.newArrayList(pageQueryPlanCustomerStatRequest.getCustomerCode()));
        }
        if (CollectionUtils.isNotEmpty(pageQueryPlanCustomerStatRequest.getCustomerAddressList())){
            queryPlanCustomerRequest.setCustomerAddressList(pageQueryPlanCustomerStatRequest.getCustomerAddressList());
        }
        if (StringUtils.isNotBlank(pageQueryPlanCustomerStatRequest.getManageEmployeeId())){
            queryPlanCustomerRequest.setManageEmployeeIdList(Lists.newArrayList(pageQueryPlanCustomerStatRequest.getManageEmployeeId()));
        }
        queryPlanCustomerRequest.setSubCustomerName(pageQueryPlanCustomerStatRequest.getCustomerName());
        queryPlanCustomerRequest.setSubCustomerAddressName(pageQueryPlanCustomerStatRequest.getCustomerAddressName());
        queryPlanCustomerRequest.setDir(pageQueryPlanCustomerStatRequest.getDir());
        queryPlanCustomerRequest.setAsc(pageQueryPlanCustomerStatRequest.getAsc());
        queryPlanCustomerRequest.setStart(pageQueryPlanCustomerStatRequest.getStart());
        queryPlanCustomerRequest.setLimit(pageQueryPlanCustomerStatRequest.getLimit());
        queryPlanCustomerRequest.setStatus(pageQueryPlanCustomerStatRequest.getStatus());
        //查询调整数据
        if (pageQueryPlanCustomerStatRequest.getIsAdjustCount()) {
            queryPlanCustomerRequest.setAdjustCount(0);
        }
        SalesStatBizTypeEnum statBizTypeEnum = SalesStatBizTypeEnum.match(dimension.getBizType());
        switch (statBizTypeEnum){
            case SALESMAN:
                if (StringUtils.isNotBlank(pageQueryPlanCustomerStatRequest.getManageEmployeeId())){
                    if (!pageQueryPlanCustomerStatRequest.getManageEmployeeId().equals(dimension.getBizId())){
                        throw new FacadeException("OTS-02-001-00-15-0012");
                    }
                }else {
                    queryPlanCustomerRequest.setManageEmployeeIdList(Lists.newArrayList(dimension.getBizId()));
                }
                break;
            case SALES_DEPARTMENT:
                queryPlanCustomerRequest.setOrgSalesDepartmentCodeList(Lists.newArrayList(dimension.getBizId()));
                break;
            case SALES_CHANNEL:
                queryPlanCustomerRequest.setOrgSalesChannelCodeList(Lists.newArrayList(dimension.getBizId()));
                break;
            case SALES_ORGANIZATION:
                queryPlanCustomerRequest.setOrgSalesOrganizationCodeList(Lists.newArrayList(dimension.getBizId()));
                break;
            case BUSINESS_UNIT:
                queryPlanCustomerRequest.setOrgBusinessUnitCodeList(Lists.newArrayList(dimension.getBizId()));
                break;
            default:
                throw new FacadeException("OTS-02-002-02-15-007");
        }
        queryPlanCustomerRequest.setPoolType(1);
        PageQueryPlanCustomerResponse pageQueryPlanCustomerResponse = boSalesPlanCustomerIndexService.pageQueryPlanCustomer(queryPlanCustomerRequest);
        if (pageQueryPlanCustomerResponse == null || CollectionUtils.isEmpty(pageQueryPlanCustomerResponse.getResult())){
            return Result.success(new PageResult<>(Lists.newArrayList(),0));
        }
        List<SalesPlanStatCustomerSDO> result = pageQueryPlanCustomerResponse.getResult().stream().map(boSalesPlanCustomerIndex -> {
            SalesPlanStatCustomerSDO customerSDO = new SalesPlanStatCustomerSDO();
            BeanUtils.copyProperties(boSalesPlanCustomerIndex,customerSDO);
            customerSDO.setCustomerName(boSalesPlanCustomerIndex.getSubCustomerName());
            customerSDO.setCustomerAddressName(boSalesPlanCustomerIndex.getSubCustomerAddressName());
            return customerSDO;
        }).collect(Collectors.toList());
        return Result.success(new PageResult<>(result,pageQueryPlanCustomerResponse.getTotal()));
    }

    @FacadeInvoker
    @Override
    public Result<SalesPlanSubTotalResponse> subTotalSalesPlanStatCustomer(SalesPlanStatCustomerSubTotalRequest salesPlanStatCustomerSubTotalRequest) {
        SalesPlanSDO salesPlan = salesPlanCommonService.checkSalesPlan(salesPlanStatCustomerSubTotalRequest.getPlanId());
        DimensionDTO dimension = salesPlanCommonService.checkBizType(salesPlan, salesPlanStatCustomerSubTotalRequest);
        SalesPlanStatCustomerSubTotalRepoRequest subTotalRepoRequest = new SalesPlanStatCustomerSubTotalRepoRequest();
        subTotalRepoRequest.setPlanId(salesPlanStatCustomerSubTotalRequest.getPlanId());
        subTotalRepoRequest.setCustomerCode(salesPlanStatCustomerSubTotalRequest.getCustomerCode());
        if (CollectionUtils.isNotEmpty(salesPlanStatCustomerSubTotalRequest.getCustomerAddressList())){
            subTotalRepoRequest.setCustomerAddressList(salesPlanStatCustomerSubTotalRequest.getCustomerAddressList());
        }
        subTotalRepoRequest.setEmployeeId(salesPlanStatCustomerSubTotalRequest.getManageEmployeeId());
        //查询调整数据
        if (salesPlanStatCustomerSubTotalRequest.getIsAdjustCount()) {
            subTotalRepoRequest.setAdjustCount(0);
        }
        SalesStatBizTypeEnum statBizTypeEnum = SalesStatBizTypeEnum.match(dimension.getBizType());
        switch (statBizTypeEnum){
            case SALESMAN:
                if (StringUtils.isNotBlank(salesPlanStatCustomerSubTotalRequest.getManageEmployeeId())){
                    if (!salesPlanStatCustomerSubTotalRequest.getManageEmployeeId().equals(dimension.getBizId())){
                        throw new FacadeException("OTS-02-001-00-15-0012");
                    }
                }else {
                    subTotalRepoRequest.setEmployeeId(dimension.getBizId());
                }
                break;
            case SALES_DEPARTMENT:
                subTotalRepoRequest.setOrgSalesDepartmentCode(dimension.getBizId());
                break;
            case SALES_CHANNEL:
                subTotalRepoRequest.setOrgSalesChannelCode(dimension.getBizId());
                break;
            case SALES_ORGANIZATION:
                subTotalRepoRequest.setOrgSalesOrganizationCode(dimension.getBizId());
                break;
            case BUSINESS_UNIT:
                subTotalRepoRequest.setOrgBusinessUnitCode(dimension.getBizId());
                break;
            default:
                throw new FacadeException("OTS-02-002-02-15-007");
        }
        subTotalRepoRequest.setPoolType(1);
        SalesPlanSubTotalResponse salesPlanSubTotalResponse = salesPlanCustomerStatRepository.subTotalSalesPlanStatCustomer(subTotalRepoRequest);
        BigDecimal discount = (new BigDecimal(100).subtract(salesPlan.getEstimateDiscount())).divide(new BigDecimal(100),2,BigDecimal.ROUND_HALF_UP);

        if(salesPlanSubTotalResponse.getMonthCount()!= null){
            //调整汇总
            if(salesPlanStatCustomerSubTotalRequest.getIsAdjustCount()){
                //合计总调整量
                SalesPlanAdjustDetailSubTotalRequest subTotalAdjustDetailRequest = new SalesPlanAdjustDetailSubTotalRequest();
                BeanUtils.copyProperties(subTotalRepoRequest, subTotalAdjustDetailRequest);
                subTotalAdjustDetailRequest.setAdjustId(salesPlanStatCustomerSubTotalRequest.getAdjustId());
                subTotalAdjustDetailRequest.setCustomerCode(salesPlanStatCustomerSubTotalRequest.getCustomerCode());
                subTotalAdjustDetailRequest.setManageEmployeeId(subTotalRepoRequest.getEmployeeId());
                subTotalAdjustDetailRequest.setManageEmployeeId(salesPlanStatCustomerSubTotalRequest.getManageEmployeeId());
                subTotalAdjustDetailRequest.setAdjust(true);
                subTotalAdjustDetailRequest.setPlanId(null);
                SalesPlanSubTotalResponse subTotalAdjustDetailResponse = salesPlanAdjustDetailRepository.subTotalSalesPlanAdjustDetail(subTotalAdjustDetailRequest);
                salesPlanSubTotalResponse.setAdjustCount(subTotalAdjustDetailResponse.getAdjustCount());
                salesPlanSubTotalResponse.setBeforeAdjustMoney(subTotalAdjustDetailResponse.getBeforeAdjustMoney());
                if(subTotalAdjustDetailResponse.getBeforeAdjustMoney()!=null){
                    BigDecimal adjustMoney = new BigDecimal(subTotalAdjustDetailResponse.getBeforeAdjustMoney()).multiply(discount);
                    salesPlanSubTotalResponse.setAdjustMoney(adjustMoney.longValue());
                }
                //初始任务量
                SubTotalSalesPlanLineRequest subTotalSalesPlanLineRequest = new SubTotalSalesPlanLineRequest();
                BeanUtils.copyProperties(subTotalRepoRequest, subTotalSalesPlanLineRequest);
                subTotalSalesPlanLineRequest.setPlanId(Long.valueOf(salesPlanStatCustomerSubTotalRequest.getPlanId()));
                subTotalSalesPlanLineRequest.setManageEmployeeIdList(StringUtils.isNotBlank(subTotalRepoRequest.getEmployeeId())?Lists.newArrayList(subTotalRepoRequest.getEmployeeId()):null);
                SalesPlanSubTotalResponse salesPlanSubTotalAdjustResponse = salesPlanLineRepository.subTotalSalesPlanLine(subTotalSalesPlanLineRequest);
                salesPlanSubTotalResponse.setInitTaskCount(salesPlanSubTotalAdjustResponse.getInitTaskCount());
                salesPlanSubTotalResponse.setInitBeforeTaskMoney(salesPlanSubTotalAdjustResponse.getInitBeforeTaskMoney());
                if (salesPlanSubTotalAdjustResponse.getInitBeforeTaskMoney() != null) {
                    BigDecimal initTaskMoney = new BigDecimal(salesPlanSubTotalAdjustResponse.getInitBeforeTaskMoney()).multiply(discount);
                    salesPlanSubTotalResponse.setInitTaskMoney(initTaskMoney.longValue());
                }
            }else {
                //合计总调整量
                SubTotalSalesPlanLineRequest subTotalSalesPlanLineRequest = new SubTotalSalesPlanLineRequest();
                BeanUtils.copyProperties(subTotalRepoRequest, subTotalSalesPlanLineRequest);
                subTotalSalesPlanLineRequest.setPlanId(Long.valueOf(salesPlanStatCustomerSubTotalRequest.getPlanId()));
                subTotalSalesPlanLineRequest.setManageEmployeeIdList(StringUtils.isNotBlank(subTotalRepoRequest.getEmployeeId())?Lists.newArrayList(subTotalRepoRequest.getEmployeeId()):null);
                SalesPlanSubTotalResponse salesPlanSubTotalAdjustResponse = salesPlanLineRepository.subTotalSalesPlanLine(subTotalSalesPlanLineRequest);
                salesPlanSubTotalResponse.setAdjustCount(salesPlanSubTotalAdjustResponse.getAdjustCount());
                salesPlanSubTotalResponse.setAdjustOutboundMoney(salesPlanSubTotalAdjustResponse.getAdjustOutboundMoney());
                salesPlanSubTotalResponse.setBeforeAdjustMoney(salesPlanSubTotalAdjustResponse.getBeforeAdjustMoney());
                if (salesPlanSubTotalResponse.getBeforeAdjustMoney() != null) {
                    BigDecimal adjustMoney = new BigDecimal(salesPlanSubTotalResponse.getBeforeAdjustMoney()).multiply(discount);
                    salesPlanSubTotalResponse.setAdjustMoney(adjustMoney.longValue());
                }
                //初始任务量
                if (salesPlan.getStatus() >= SalesPlanStatusEnum.PUBLISHED.getCode()) {
                    salesPlanSubTotalResponse.setInitTaskCount(salesPlanSubTotalAdjustResponse.getInitTaskCount());
                    salesPlanSubTotalResponse.setInitBeforeTaskMoney(salesPlanSubTotalAdjustResponse.getInitBeforeTaskMoney());
                    if (salesPlanSubTotalAdjustResponse.getInitBeforeTaskMoney() != null) {
                        BigDecimal initTaskMoney = new BigDecimal(salesPlanSubTotalAdjustResponse.getInitBeforeTaskMoney()).multiply(discount);
                        salesPlanSubTotalResponse.setInitTaskMoney(initTaskMoney.longValue());
                    }
                } else {
                    salesPlanSubTotalResponse.setInitTaskCount(0);
                    salesPlanSubTotalResponse.setInitBeforeTaskMoney(0L);
                    salesPlanSubTotalResponse.setInitTaskMoney(0L);
                }
            }
            //合计crm回复量
            SubTotalCompanyReturnCountRequest subTotalCompanyReturnCountRequest = new SubTotalCompanyReturnCountRequest();
            BeanUtils.copyProperties(subTotalRepoRequest,subTotalCompanyReturnCountRequest);
            subTotalCompanyReturnCountRequest.setPlanId(Long.valueOf(salesPlanStatCustomerSubTotalRequest.getPlanId()));
            SubTotalCompanyReturnCountResponse subTotalCompanyReturnCountResponse = planScItemExtendService.subTotalCompanyReturnCount(subTotalCompanyReturnCountRequest);
            salesPlanSubTotalResponse.setReturnCount(getMoney(subTotalCompanyReturnCountResponse.getReturnCount()));
            salesPlanSubTotalResponse.setBeforeReturnMoney(getMoney(subTotalCompanyReturnCountResponse.getBeforeReturnMoney()));
            BigDecimal returnMoney = new BigDecimal(salesPlanSubTotalResponse.getBeforeReturnMoney()).multiply(discount);
            salesPlanSubTotalResponse.setReturnMoney(returnMoney.longValue());
            salesPlanSubTotalResponse.setReturnOutboundMoney(getMoney(subTotalCompanyReturnCountResponse.getReturnOutboundMoney()));

            //合计crm合同量
            SubTotalCompanyCrmContractCountRequest subTotalCompanyCrmContractCountRequest = new SubTotalCompanyCrmContractCountRequest();
            subTotalCompanyCrmContractCountRequest.setContractYear(DateUtils.toDateStr(Long.valueOf(salesPlan.getPlanTime()),"yyyy"));
            subTotalCompanyCrmContractCountRequest.setOrgBusinessUnitCode(salesPlan.getOrgBusinessUnitCode());
            Result<Contract> contractResult = contractService.subTotalCompanyCrmContractCount(subTotalCompanyCrmContractCountRequest);
            Contract contract = contractResult.getResult();
            setSubTotalContractCount(DateUtils.toDateStr(Long.valueOf(salesPlan.getPlanTime()),"MM"),contract,salesPlanSubTotalResponse);
        }

        return Result.success(salesPlanSubTotalResponse);
    }

    public void setSubTotalContractCount(String month, Contract contract,SalesPlanSubTotalResponse salesPlanSubTotalResponse){
        Long crmMonthContractCount = null;
        Long crmBeforeMonthContractMoney = null;
        Long crmMonthContractMoney = null;
        switch (month){
            case "01" :
                crmMonthContractCount = getCount(contract.getJanQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getJanTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getJanAmount());
                break;
            case "02" :
                crmMonthContractCount = getCount(contract.getFebQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getFebTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getFebAmount());
                break;
            case "03" :
                crmMonthContractCount = getCount(contract.getMarQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getMarTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getMarAmount());
                break;
            case "04" :
                crmMonthContractCount = getCount(contract.getAprQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getAprTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getAprAmount());
                break;
            case "05" :
                crmMonthContractCount = getCount(contract.getMayQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getMayTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getMayAmount());
                break;
            case "06" :
                crmMonthContractCount = getCount(contract.getJuneQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getJuneTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getJuneAmount());
                break;
            case "07" :
                crmMonthContractCount = getCount(contract.getJulyQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getJulyTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getJulyAmount());
                break;
            case "08" :
                crmMonthContractCount = getCount(contract.getAugQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getAugTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getAugAmount());
                break;
            case "09" :
                crmMonthContractCount = getCount(contract.getSeptQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getSeptTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getSeptAmount());
                break;
            case "10" :
                crmMonthContractCount = getCount(contract.getOctQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getOctTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getOctAmount());
                break;
            case "11" :
                crmMonthContractCount = getCount(contract.getNovQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getNovTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getNovAmount());
                break;
            case "12" :
                crmMonthContractCount = getCount(contract.getDecQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getDecTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getDecAmount());
                break;
            default:
                crmMonthContractCount = 0L;
                crmBeforeMonthContractMoney = 0L;
                crmMonthContractMoney = 0L;
        }

        salesPlanSubTotalResponse.setCrmMonthContractCount(crmMonthContractCount);
        salesPlanSubTotalResponse.setCrmBeforeMonthContractMoney(crmBeforeMonthContractMoney);
        salesPlanSubTotalResponse.setCrmMonthContractMoney(crmMonthContractMoney);
    }

    private Long getCount(Integer i){
        if(i == null){
            return 0L;
        }
        return i.longValue();
    }

    private Long getMoney(Long l){
        if(l == null){
            return 0L;
        }
        return l;
    }

}
